//
//  networkTool.swift
//  VO_Yuejie
//
//  Created by laichunhui on 15/9/17.
//  Copyright © 2015年 lch. All rights reserved.
//
import UIKit
import Alamofire

/// 网络工具单例
class NetworkTools {

    // 网络请求完成回调的数据类型
    typealias RequestFinishedCallBack = (result: AnyObject?, error: NSError?) -> ()
   
    /// 网络工具单例
    static let sharedTools = NetworkTools()
    
    // MARK: - 应用程序信息
    private let appKey = "2923156246"
    private let appSecret = "07559ae30fb104aa96834e6133f71641"
    /// 授权回调地址
    let redirectURI = "http://sns.whalecloud.com/sina2/callback"
    
    /// 创建 token 字典
    /// 目前有很多公司，都会封装自己的网络访问方法，会把用户身份安全的代码全部封装！
    private var tokenParams: [String: AnyObject]? {
        // 1. 判断用户账户中是否存在token，如果没有存在说明用户没有登录，或者 token 过期
//        guard let token = "YiFD9p2Igd5tCJsYY0sK"  else {
//            // token 不存在
//            return nil
//        }
        let token = "YiFD9p2Igd5tCJsYY0sK"
        // 2. 返回 token 字典
        return ["token": token]
    }
    
    
// MARK: - 加载数据
    /// 加载主题数据
    ///
    /// - parameter offset:     设置主题插入队列的偏移，默认为0
    func loadTopics(count: Int, offset: Int, finished: RequestFinishedCallBack) {
        // 1. 建立 token 字典
        guard var params = tokenParams else {
            // 如果 token 为 nil，需要通知控制器，不再执行网络方法
            finished(result: nil, error: NSError(domain: "errorLoading", code: -1002, userInfo: ["message": "token 为 nil"]))
            return
        }
        
        // 2. 参数设置
        params["count"] = count
        params["offset"] = offset
        
        // 3. 发起网络请求
        request(.GET, urlString: Yuejie.timeline_URLString, parameters: params, finished: finished)
    }
    
    
    /// 加载主题详情 
    // http://apiv3.pento.cn/api/v3/stream/board/532/pin.json?
    
    func loadTopicDetail(value: String, finished: RequestFinishedCallBack) {
        
        let urlString = "http://apiv3.pento.cn/api/v3/stream/board/" + value + "/pin.json?"
        print(urlString)

        request(.GET, urlString: urlString, parameters: nil, finished: finished)
    }
    
    
//    // MARK: - 用户信息
//    /// 加载用户
//    ///
//    /// - parameter uid:         uid
//    /// - parameter finished:    完成回调
//    /// - see: [http://open.weibo.com/wiki/2/users/show](http://open.weibo.com/wiki/2/users/show)
//    func loadUserInfo(uid: String, finished: RequestFinishedCallBack) {
//        
//        // 1. 建立 token 字典
//        guard var params = tokenParams else {
//            // 如果 token 为 nil，需要通知控制器，不再执行网络方法
//            finished(result: nil, error: NSError(domain: "errorLoading", code: -1002, userInfo: ["message": "token 为 nil"]))
//            return
//        }
//        
//        // 2. 向字典中增加参数
//        params["uid"] = uid
//        
//        // 2. 发起网络请求
//        request(.GET, urlString: SinaUserInfo_URL, parameters: params, finished: finished)
//    }
//    
    
    // MARK: - 身份验证
    /// OAuth 登录 URL 地址
    /// 计算型属性，类似于函数，必须有返回值，同时不能有参数，使用频率，使用属性，代码的语义会更清晰
    var oauthURL: NSURL {
        let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(appKey)&redirect_uri=\(redirectURI)"
        
        return NSURL(string: urlString)!
    }
    
    /// 使用 code 加载 token
    ///
    /// - parameter code:     code
    /// - parameter finished: 完成回调
    func loadAccessToken(code: String, finished: RequestFinishedCallBack) {
        let params = ["client_id": appKey,
            "client_secret": appSecret,
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": redirectURI]
        
        request(.POST, urlString: "https://api.weibo.com/oauth2/access_token", parameters: params, finished: finished)
        
        // 测试代码
        //        // 1. 设置响应数据格式为二进制数据 AFN 不会做 JSON 反序列化
        //        responseSerializer = AFHTTPResponseSerializer()
        //
        //        // 2. 测试网络代码 － Swift 开发中，凡是碰到 AnyObject 要想使用，就必须转换！
        //        request(.POST, urlString: "https://api.weibo.com/oauth2/access_token", parameters: params) { (result, error) -> () in
        //            // result 是一个 NSData
        //            // 将数据转换成 NSString
        //            let string = NSString(data: result as! NSData, encoding: NSUTF8StringEncoding)
        //
        //            // {"access_token":"2.00ml8IrFKlq63E7ccdbba6c5OotBTD","remind_in":"157679999","expires_in":157679999,"uid":"5365823342"}
        //            // 提示：JSON 反序列化的时候，如果数字没有引号，转换成 NSNumber，可能会导致 KVC 的崩溃！
        //            print(string)
        //        }
    }
    
    // MARK: - 封装 Ala 网络访问方法
    /// 发起网络请求
    ///
    /// - parameter method:     method GET / POST
    /// - parameter urlString:  urlString
    /// - parameter parameters: 参数字典
    /// - parameter finished:   完成回调
    private func request(method: Alamofire.Method, urlString: String, parameters: [String: AnyObject]?, finished: RequestFinishedCallBack) {
        
        Alamofire.request(method, urlString, parameters: parameters).responseJSON {
            (response) -> Void in
       
            finished(result: response.result.value, error: response.result.error)
        }
    }
    
    /// 上传文件
    ///
    /// - parameter urlString:  urlString
    /// - parameter data:       要上传文件的二进制数据
    /// - parameter parameters: 参数字典
    /// - parameter finished:   完成回调
    private func uploading(urlString: String, data: NSData, parameters: [String: AnyObject]?, finished: RequestFinishedCallBack) {
        
            /**
            1. 要上传文件的二进制数据
            2. `服务器提供的`接口文件名称
            3. 保存在服务器的文件名，通常可以乱写
            4. mimeType: 客户端高速服务器，上传图片的类型
            contentType: 服务器高速客户端数据的类型
            
            格式：大类型/小类型
            如果不想告诉服务器文件类型，可以使用 application/octet-stream
            
            如果开发中碰到上传多个文件，可以用一个 for 顺序添加
            */
        Alamofire.upload(.POST, urlString, multipartFormData: { (multipartFormData) in
                
                multipartFormData.appendBodyPart(data: data, name: "pic", fileName: "xxx.png", mimeType: "image/png")
                
                guard let params = parameters else {
                    return
                }
                
                for (k, v) in params {
                    let value = v as! String
                    multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: k)
                }
            }) { (encodingResult) -> Void in
                switch encodingResult {
                case .Success(let upload, _, _):
                    upload.responseJSON { response in
                        finished(result: response.result.value, error: response.result.error)
                    }
                case .Failure(let encodingError):
                    printLog(encodingError)
                    finished(result: nil, error: nil)
                }
        }
    }
    
    
    /// 下载文件
    ///
    /// - parameter urlString:  下载路径
    
    /// - parameter finished:   完成回调
    func downloading(urlString urlString: String) {
  
        Alamofire.download(.GET, urlString) { temporaryURL, response in
            
            let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask)[0]
            let pathComponent = response.suggestedFilename
        
            
            return directoryURL.URLByAppendingPathComponent(pathComponent!)
        }
        
    }

}